﻿using Digitalmes.Core.Common.Interfaces;
using Digitalmes.Core.Domain.Eitites;
using Digitalmes.Core.Messages;
using Digitalmes.Core.Services;
using ThingsEdge.Contracts;

namespace Digitalmes.Infrastructure.Scada.Handlers;

/// <summary>
/// 转盘数据存档处理器
/// </summary>
internal sealed class ArchiveHandler(ITurntableArchiveService archiveService,
    IMessageQueue<TurntableArchiveMessage> archiveMQ,
    ILogger<ArchiveHandler> logger) : IScadaNoticeHandler
{
    public async Task HandleAsync(RequestMessage message, CancellationToken cancellationToken = default)
    {
        var rotation0 = message.Self().GetInt(); // 1->正转；2->反转
        var rotation = rotation0 switch
        {
            1 => Rotation.Forward,
            2 => Rotation.Reverse,
            _ => Rotation.Unkown,
        };

        if (rotation is Rotation.Unkown)
        {
            return;
        }

        logger.LogInformation("转台数据存档，数据：{@Value}", message.Values.Select(s => new { s.Address, s.Value }));

        var forwardRotationTime = message.GetData(TagDefinition.PLC_Archive_ForwardRotationTime)?.GetDInt() ?? 0;
        var reverseRotationTime = message.GetData(TagDefinition.PLC_Archive_ReverseRotationTime)?.GetDInt() ?? 0;
        var repeatabilityA = message.GetData(TagDefinition.PLC_Archive_Repeatability_A)?.GetReal() ?? 0;
        var repeatabilityB = message.GetData(TagDefinition.PLC_Archive_Repeatability_B)?.GetReal() ?? 0;
        var repeatabilityAxialA = message.GetData(TagDefinition.PLC_Archive_Repeatability_Axial_A)?.GetReal() ?? 0;
        var repeatabilityAxialB = message.GetData(TagDefinition.PLC_Archive_Repeatability_Axial_B)?.GetReal() ?? 0;

        // 正转时清空反转数据，反之一样
        // 轴向数据仅在正转时才检测
        if (rotation is Rotation.Forward)
        {
            reverseRotationTime = 0;
            repeatabilityB = 0;
        }
        else if (rotation is Rotation.Reverse)
        {
            forwardRotationTime = 0;
            repeatabilityA = 0;
            repeatabilityAxialA = 0;
            repeatabilityAxialB = 0;
        }

        TurntableArchiveRecord model = new()
        {
            ArchiveTime = DateTime.Now,
            ForwardRotationTime = FormatValue(forwardRotationTime * 0.1, 1), // 实际值需*0.1
            ReverseRotationTime = FormatValue(reverseRotationTime * 0.1, 1), // 实际值需*0.1
            Repeatability1 = FormatValue(repeatabilityA * 0.1, 3), // 实际值需*0.1
            Repeatability2 = FormatValue(repeatabilityB * 0.1, 3), // 实际值需*0.1
            RepeatabilityAxial1 = FormatValue(repeatabilityAxialA * 0.1, 3), // 实际值需*0.1
            RepeatabilityAxial2 = FormatValue(repeatabilityAxialB * 0.1, 3), // 实际值需*0.1
            Rotation = rotation,
        };
        await archiveService.ArchiveAsync(model).ConfigureAwait(false);
        await archiveMQ.EnqueueAsync(new TurntableArchiveMessage(
            model.ForwardRotationTime,
            model.ReverseRotationTime,
            model.Repeatability1,
            model.Repeatability2,
            model.RepeatabilityAxial1,
            model.RepeatabilityAxial2,
            model.Rotation), cancellationToken).ConfigureAwait(false);
    }

    private static double FormatValue(double value, int digits)
    {
        return Math.Round(value, digits);
    }
}
